#include <stdio.h>
#include <stdlib.h>
#include <acev/rcu.h>
#include <signal.h>

main(
     int argc,     // Anzahl Kommandozeilenparameter + Programmname
     char *argv[]  // Programmname + Kommandozeilenparameter als Strings
     )
{
  // Marker fuer Zeitmessung
  unsigned long long start, stop, rcu_get_ticks();

  // Zeiger auf RC-Adressraum
  volatile unsigned long *rcu;

  // RC initialisieren
  rcu_init();
  // Zeiger auf RC-Adressraum holen
  rcu = rcu_get_s0(NULL);

  // Speicher für ganzes 256x256 Bild, Werte 0 ... 255
  unsigned char image[256][256];
	
  // Zeiger auf aktuellen Bildpunkt
  unsigned char *p;

  // Iterationsvariable
  unsigned int m, n;
	
  // Eingabe- und Ausgabedatei
  FILE *infile, *outfile;

  // Aufrufparameter prüfen
  if (argc != 3) {
    printf("Falscher Aufruf, richtig: `./contrast Eingabe.pgm Ausgabe.pgm'\n");
    exit(1);
  }  

  // Merke Startzeit der Berechnung
  start = rcu_get_ticks();

  // Eingabedatei oeffnen
  if ((infile = fopen(argv[1], "r")) == NULL) {
    printf("Eingabedatei %s konnte nicht geoeffnet werden.\n", argv[1]);
    exit(2);
  }

  // Ausgabedatei oeffnen
  if ((outfile = fopen(argv[2], "w")) == NULL) {
    printf("Ausgabedatei %s konnte nicht geoeffnet werden.\n", argv[2]);
    exit(3);
  }     

  // Reiche PGM Kopfdatensatz direkt durch
  fgets((void*)image, 80, infile);
  fputs((void*)image,  outfile);
  fgets((void*)image, 80, infile);
  fputs((void*)image,  outfile);
  fgets((void*)image, 80, infile);
  fputs((void*)image,  outfile);
  
  // lese gesamtes Feld von Bildpunkten auf einen Satz
  fread(image, sizeof(unsigned char), 256*256, infile);

  for (m = 0; m < 2; ++m)
    {
      for (n = 0, p = (void*) image; n < 256*256; ++p, ++n)
	{
	  switch (m)
	    {
	    case 0:
	      rcu[31] = *p;
	      break;
	    case 1:
	      rcu[0] = *p;
	      *p = rcu[0];
	      break;
	    }
	}
    }

  // gebe gesamtes Feld von Bildpunkten auf einen Satz aus
  fwrite(image, sizeof(unsigned char), 256*256, outfile);

  // Dateien schliessen
  fclose(infile);
  fclose(outfile);

  // merke Stopzeit
  stop = rcu_get_ticks();
        
  // Gebe Ergebnis der Zeitmessung in Mikrosekunden aus
  printf("Zeit: %lld us\n", (stop-start)/TICKS_PER_USEC);

  // Programm mit Status `Kein Fehler' beenden
  exit(0);

}
